﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace TCPClient
{
    public partial class Form1 : Form
    {
        public Socket _newClient;
        public bool _isConnect;
        public Thread _connectThread;
        public String STRING_DISCONNECT_MESSAGE = "disconnected.";
        public String STRING_HANDUP_MESSAGE = "handup.";

        public delegate void IncomeInvoke(string message);
        
        public Form1()
        {
            InitializeComponent();
            disConnectButton.Enabled = false;
        }

        public void Connect()
        {
            _newClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            string serverIp = serverIpTextBox.Text.Trim();
            int serverPort = Convert.ToInt32(serverPortTextPort.Text.Trim());
            IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), serverPort);
            
            try
            {
                _newClient.Connect(serverEndPoint);
                connectButton.Enabled = false;
                disConnectButton.Enabled = true;
                _isConnect = true;
                SendMsgButton.Enabled = _isConnect;
                DateTimeOffset now = DateTimeOffset.Now;
                SendMessage(clientNameTextBox.Text.ToString() + " is now on line at " + now.ToString("G") + ".");
            }
            catch(SocketException e)
            {
                MessageBox.Show("Failed, "+e.Message);
                return;
            }

            ThreadStart _myThreadDelegate = new ThreadStart(ReceiveMsg);
            _connectThread = new Thread(_myThreadDelegate);
            _connectThread.Start();
        }

        public void ReceiveMsg()
        {
            while (_isConnect)
            {
                byte[] data = new byte[1024];
                int recv = _newClient.Receive(data);
                String stringData = Encoding.UTF8.GetString(data, 0, recv).ToString();
                ShowMsg(stringData + "\r\n");

                if (Encoding.UTF8.GetString(data, 0, recv).ToString().Contains(STRING_HANDUP_MESSAGE))
                {
                    DisConnect();
                }

            }
        }

        public void ShowMsg(string msg)
        {
            if (receiveMsgRichTextBox.InvokeRequired)
            {
                IncomeInvoke _myinvoke = new IncomeInvoke(ShowMsg);
                receiveMsgRichTextBox.Invoke(_myinvoke, new object[] { msg });
            }
            else
            {
                receiveMsgRichTextBox.AppendText(msg);
            }
        }
       
        private void SendMsg_Click(object sender, EventArgs e)
        {
            String messageToSend = clientNameTextBox.Text.ToString() + " says: " + messageToSendTextBox.Text.ToString();
            SendMessage(messageToSend);
            messageToSendTextBox.Text = "";
        }

        private void SendMessage(String messageToSend)
        {
            try
            {
                int messageLength = messageToSend.Length;
                byte[] data = new byte[messageLength];
                data = Encoding.UTF8.GetBytes(messageToSend);
                _newClient.Send(data);
            }
            catch (Exception e) 
            {
                _newClient.Close();
                _isConnect = false;
                connectButton.Enabled = true;
                disConnectButton.Enabled = false;
                SendMsgButton.Enabled = _isConnect;
                MessageBox.Show("Failed, " + e.Message);
                return;
            }
        }

        private void Connect_Click(object sender, EventArgs e)
        {
            if (clientNameTextBox.Text.ToString() == "")
            {
                MessageBox.Show("Please enter your user name fisrt.");
            }
            else
            {
                Connect();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DisConnect();
        }

        private void disConnectButton_Click(object sender, EventArgs e)
        {
            DisConnect();
        }

        private void DisConnect()
        {
            if (_isConnect)
            {
                String messageToSend = clientNameTextBox.Text.ToString() + " " + STRING_DISCONNECT_MESSAGE;
                SendMessage(messageToSend);

                //_newClient.Shutdown(SocketShutdown.Both);
                _newClient.Close();
                _connectThread.Interrupt();
                _connectThread.Abort();
            }
            _isConnect = false;
            connectButton.Enabled = true;
            disConnectButton.Enabled = false;
            SendMsgButton.Enabled = _isConnect;
        }
        
    }
}
